package com.hqyj.aop;

import com.hqyj.dao.UserInfoMapper;
import com.hqyj.excepiton.JwtException;
import com.hqyj.excepiton.PowerException;
import com.hqyj.utile.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 项目:exam-springboot-230701
 * 描述:
 * 时间:2023/10/7 15:39
 * 作者:admin
 * 版本:1.0
 **/
@Component
@Aspect
@Slf4j
public class PowerAop {

    @Resource
    UserInfoMapper userInfoMapper;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    //定义切入点
    @Pointcut("execution(* com.hqyj.controller.*.*(..))")
    public void point(){

    }

    @Before("point()")
    public void before(JoinPoint joinPoint) throws PowerException, JwtException {

        //获取自定义权限注解
        MethodSignature methodSignature =(MethodSignature) joinPoint.getSignature();
        PowerAnnotion p =methodSignature.getMethod().getAnnotation(PowerAnnotion.class);
        if(p!=null){
            //获取request对象
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //获取token
            String token = request.getHeader("Authorization");
            if(StringUtils.isEmpty(token)){
                throw new JwtException(300,"请重新登录","token为空");
            }
            //获取用户名
            String userName = JwtUtil.getClaimByName(token,"userName").asString();
            String key = userName+":power";
            List<String> list =null;
            //查询缓存是否有数据
            Object obj = redisTemplate.opsForValue().get(key);
            if(obj==null){
                log.info("缓存中没有数据，从数据库查询获取");
                //查询数据库
                 list = userInfoMapper.queryRoleByUserName(userName);
                //把数据存入redis缓存中
                redisTemplate.opsForValue().set(key,list,2, TimeUnit.MINUTES);
            }else{
                log.info("缓存中有数据，从缓存中获取数据");
                //从缓存中去数据
                list = (List<String>)obj;
            }

            boolean is = false;
            //获取自定义注解的角色信息
            String role = p.value();
            for(String s :list){
                if(s.equals(role)){
                    is = true;
                }
            }
            if(!is){ throw  new PowerException(500,"没有权限","");

            }
        }

    }

}
